/**
 * DownloadTask.java
 * 
 * Create Version: 1.0
 * Author: 徐舟骏
 * Create Date: 2012-5-9
 */
package ysyh55.android.base.task;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Handler;
import android.widget.RelativeLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.TextView;

import ysyh55.android.base.exception.HttpException;
import ysyh55.android.base.exception.TaskResultException;
import ysyh55.android.base.http.HttpClient;
import ysyh55.android.base.http.HttpResponse;
import ysyh55.android.base.util.BeanUtils;
import ysyh55.android.base.util.DownloadCallback;

/**
 * DownloadTask 文件下载任务类
 * 
 * @author 徐舟骏
 */
public class DownloadTask extends BaseTask<DownloadCallback, Integer, Boolean> {
	/**
	 * 中止下载标志
	 */
	private Boolean interceptFlag = false;
	/**
	 * 下载进度指示条
	 */
	private ProgressBar progressBar;
	private Handler handler;
	private TextView progressText;
	private int progressCount;
	private long progressLength;
	/**
	 * 下载对话框
	 */
	private Dialog downloadDialog;
	/**
	 * 下载用HttpClient
	 */
	private HttpClient httpClient;
	/**
	 * 下载参数
	 */
	private DownloadCallback downloadCallback;

	/**
	 * @param context
	 */
	public DownloadTask(Context context, HttpClient httpClient) {
		super(context);

		this.handler = new Handler();
		this.httpClient = httpClient;
		this.progressBar = new ProgressBar(context);
		BeanUtils.setFieldValue(progressBar, "mOnlyIndeterminate", new Boolean(false));
		this.progressBar.setIndeterminate(false);
		this.progressBar
				.setProgressDrawable(context.getResources().getDrawable(android.R.drawable.progress_horizontal));
		this.progressBar.setIndeterminateDrawable(context.getResources().getDrawable(
				android.R.drawable.progress_indeterminate_horizontal));	
		
		RelativeLayout layout = new RelativeLayout(context);
		layout.addView(progressBar, new LayoutParams(LayoutParams.FILL_PARENT, 20));	
		
		LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
		lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE); 
		lp.setMargins(0, 20, 0, 0);
		this.progressText = new TextView(context);
		progressText.setLayoutParams(lp);
		layout.addView(progressText);

		this.downloadDialog = new AlertDialog.Builder(context).setView(layout).setTitle("文件下载中")
				.setPositiveButton("取消", new OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {
						interceptFlag = true;
					}
				}).create();
	}

	protected void onPreExecute() {
		super.onPreExecute();
		interceptFlag = false;
		progressBar.setProgress(0);
		downloadDialog.setCancelable(false);
		downloadDialog.show();
	}

	protected void onProgressUpdate(Integer... values) {
		super.onProgressUpdate(values);
		progressBar.setProgress(values[0]);
		handler.post(runnableUi);
	}
	
	protected void onError() {
		super.onError();
		progressBar.setProgress(0);
		downloadDialog.dismiss();
	}

	/*
	 * (non-Javadoc)
	 * @see ysyh55.android.base.task.BaseTask#onSuccess(java.lang.Object)
	 */
	@Override
	protected void onSuccess(Boolean result) {
		progressBar.setProgress(100);
		downloadDialog.dismiss();
		if (!this.interceptFlag) {
			this.downloadCallback.doCallback();
		}
	}

	/*
	 * (non-Javadoc)
	 * @see ysyh55.android.base.task.BaseTask#doInBack(Params[])
	 */
	@Override
	protected Boolean doInBack(DownloadCallback... params) throws HttpException, IOException, TaskResultException {
		this.downloadCallback = params[0];

		HttpResponse rp = httpClient.get(this.downloadCallback.getUrl(), this.downloadCallback.getParams());
		Long length = rp.getContentLength();
		InputStream is = rp.asStream();
		File saveFile = new File(this.downloadCallback.getSavePath());
		if (saveFile.getParentFile().exists() && saveFile.getParentFile().isFile()) {
			saveFile.getParentFile().delete();
		}
		saveFile.getParentFile().mkdirs();

		FileOutputStream os = new FileOutputStream(saveFile);

		try {
			Integer count = 0;
			Integer numread = -1;
			byte buf[] = new byte[1024];

			while (!interceptFlag && (numread = is.read(buf)) != -1) {
				os.write(buf, 0, numread);

				count += numread;
				int progress = (int) (((float) count / length) * 100);

				progressCount = count;
				progressLength = length;
				publishProgress(progress);
			}

			os.flush();
			return interceptFlag ? false : true;
		} finally {
			try {
				os.close();
			} finally {
				is.close();
			}
		}
	}
	
	 Runnable runnableUi = new Runnable(){
		 @Override  
         public void run() {
    	     progressText.setText(convertProgressString(progressCount,progressLength));
         } 	          
     };
     
 	private String convertProgressString(int progressCount, long progressLength) {
 		return convertSizeString(progressCount) + "/" + convertSizeString(progressLength);
 	}
 	
 	private String convertSizeString(long number) {
 		String unit = "";
 		float size = 0;
 		if(number <= 1024) {
 			return "未知大小";
 		} else if(number < 1048576) {
 			size = (float)number/(float)1024;
 			unit = "KB";
 		} else {
 			size = (float)number/(float)1048576;
 			unit = "MB"; 			
 		} 		
 		DecimalFormat formater = new DecimalFormat("#0.00");		
 		return formater.format(size) + unit;
 	}
}
